package cn.jhz.learn.blog.common.util;

import static java.util.stream.Collectors.toList;

import cn.jhz.learn.blog.common.bean.TreeNode;

import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;

public class TreeUtil {
    private static final  Comparator<TreeNode> seqComparator = (o1, o2) ->o1.getSeq() - o2.getSeq();

    private TreeUtil(){}

    private static class HolderClass{
        private final static TreeUtil instance = new TreeUtil();
    }

    private static TreeUtil getInstance(){
        return HolderClass.instance;
    }

    public static <T> List<TreeNode<T>> getTree(List<T> beanList, List<Integer> idList, List<String> levelList,
                                                List<Short> seqList){
        //TODO:并行可选
        TreeUtil util = getInstance();
        List<TreeNode<T>> nodeList = IntStream.range(0, beanList.size())
                        .mapToObj(i -> TreeNode.adapt(beanList.get(i), idList.get(i), levelList.get(i), seqList.get(i)))
                        .collect(toList());

        return util.listToTree(Optional.of(nodeList));
    }

    private <T> List<TreeNode<T>> listToTree(Optional<List<TreeNode<T>>> levelList){
        if(levelList.map(List::isEmpty).get()) return Lists.newArrayList();

        // level -> [dept1,dept2,...]
        Multimap<String, TreeNode<T>> levelMap = LinkedListMultimap.create();
        List<TreeNode<T>> rootList = Lists.newArrayList();

        levelList.get()
                .forEach(
                        node -> {
                            levelMap.put(node.getLevel(), node);
                            node.setLevelMap(Optional.of(levelMap));
                            if(LevelUtil.ROOT.equals(node.getLevel()))
                                rootList.add(node);
                        });
        //按照seq从小到大排序
        rootList.sort(seqComparator);
        //通过递归创建树
        transformTree(rootList, LevelUtil.ROOT, levelMap);

        return rootList;
    }

    private <T> void transformTree(List<TreeNode<T>> levelList, String level, Multimap<String, TreeNode<T>> levelMap){
        /* 遍历该层的每个元素 */
        /* 处理当前层级的数据 */
        levelList.forEach(
                tempNode -> {
                    String nextLevel = LevelUtil.calculateLevel(level, tempNode.getId());
                    /* 处理下一层 */
                    List<TreeNode<T>> tempList = Lists.newArrayList(levelMap.get(nextLevel));
                    if(!tempList.isEmpty()){
                        /*排序*/
                        tempList.sort(seqComparator);
                        /* 设置下一层部门 */
                        tempNode.setChildNodeList(Optional.of(tempList));
                        /* 进入到下一层处理 */
                        transformTree(tempList, nextLevel, levelMap);
                    }
                });
    }
}
